package com.taomus.mytools.lang.groovy;

import groovy.lang.GroovyClassLoader;
import groovy.lang.GroovyClassLoader.InnerLoader;
import groovy.lang.GroovyCodeSource;
import groovy.lang.GroovyObject;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.LinkedHashMap;
import java.util.Map;

import org.codehaus.groovy.control.CompilationFailedException;
import org.codehaus.groovy.runtime.IOGroovyMethods;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.taomus.mytools.helper.stream.StreamHelper;
import com.taomus.mytools.lang.ILanguageHelper;
import com.taomus.mytools.lang.IMethod;

public class GroovyHelper extends ILanguageHelper {
	private static Logger logger = LoggerFactory.getLogger(GroovyHelper.class);
	/**
	 * 类加载器
	 */
	private final static ClassLoader parentLoader = Thread.currentThread()
			.getContextClassLoader();
	/**
	 * Groovy 文件池 key : 文件名 value : 文件路径
	 */
	private final static Map<String, Class<?>> gcPool = new LinkedHashMap<String, Class<?>>();

	/**
	 * 添加Groovy路径
	 * 
	 * @param name
	 *            文件名
	 * @param path
	 *            路径
	 */
	@Override
	public void putPath(String name, String path) {
		if (!filePool.containsKey(name)) {
			logger.debug(path);
			filePool.put(name, path);
			return;
		}
		logger.error("class " + name + "已存在");
	}

	/**
	 * 获取 Groovy 实例
	 * 
	 * @param name
	 * @return GroovyObject
	 * @throws CompilationFailedException
	 * @throws IOException
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 */
	@Override
	public IMethod newInstance(String name) {
		try {
			Class<?> cc = null;
			if(name.endsWith(".groovy")){
				cc = this.getClass(name);
			}else{
				cc = gcPool.get(name);
				if (cc == null) {
					cc = this.getClass(name);
					gcPool.put(name, cc);
				}
			}
			GroovyObject obj = (GroovyObject) cc.newInstance();
			return new GroovyMethod(obj);
		} catch (InstantiationException e) {
			logger.error("GroovyHelper",e);
		} catch (IllegalAccessException e) {
			logger.error("GroovyHelper",e);
		}
		return null;

	}

	/**
	 * 获取 Groovy Class
	 * 
	 * @param name
	 * @return Class<?>
	 * @throws CompilationFailedException
	 * @throws IOException
	 */
	@Override
	public Class<?> getClass(String name) {
		try {
			
			InputStream input = null;
			if(name.endsWith(".groovy")){
				input =  StreamHelper.getInputStreamByFileName(name);
			}else{
				input = StreamHelper.getInputStreamByFileName(filePool.get(name));
			}
			GroovyClassLoader gl = new GroovyClassLoader(parentLoader);
			InnerLoader il = new InnerLoader(gl);
			String scriptText = IOGroovyMethods.getText(input);
			GroovyCodeSource  c = new GroovyCodeSource(scriptText,name+".groovy", "/groovy/script");
			Class<?> ret = il.parseClass(c);
			il.close();
			input.close();
			return ret;
		} catch (CompilationFailedException e) {
			logger.error("GroovyHelper",e);
		} catch (IOException e) {
			logger.error("GroovyHelper",e);
		}
		return null;
	}

}
